#ifndef BINSEM_H
#define BINSEM_H

#include <type.h>
#include <os/list.h>

#define BINSEM_OP_LOCK 0 // mutex acquire
#define BINSEM_OP_UNLOCK 1 // mutex release
#define BINSEMS 40 //number of all binsems

#define COND_OP_WAIT 0 
#define COND_OP_SIGNAL 1 
#define COND_OP_BROADCAST 2
#define CONDS 40 //number of all binsems

#define BARRIER_WAIT 0 // mutex acquire
#define BARRIER_WAKEUP 1 // mutex release
#define BARRIERS 40 //number of all binsems

#define MAX_MBOX_LENGTH (64)
#define BOXS 40

extern void init_binsems();
extern int get_binsem(int key);
extern int op_binsem(int binsem_id, int op);

typedef struct cond{
    int num_waiting;
    list_head list;
}cond_t;
extern void init_conds();
extern int get_cond(int key);
extern int op_cond(int cond_id, int op);

typedef struct barrier{
    int num_waiting;
    int num_reached;
    list_head list;
}barrier_t;
extern void init_barriers();
extern int get_barrier(int key, unsigned count);
extern int op_barrier(int barrier_id);

typedef struct kmailbox{
    int count;
    char mails[2][MAX_MBOX_LENGTH];
}kmailbox_t;
extern void send_mailbox(int mailbox, void *msg, int msg_length);
extern void recv_mailbox(int mailbox, void *msg, int msg_length);

#endif // BINSEM_H